package com.xsh.daw;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.xsh.daw.FileUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class PluginManage extends AppCompatActivity implements CopyCallback
{
    private static final int REQUEST_CODE_PICK_FILE = 1;
    private String bestAbi;
    private String sharedDir;
    private String userImportDir;
    private File appDir;
    private EditText b;
    private TextView debug;
    private LinearLayout rightPlugins;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_plugin_manage);
        TextView a = findViewById(R.id.defaultPlugin);
        debug = findViewById(R.id.debug);
        b = findViewById(R.id.userImportDir);
        sharedDir = getApplicationInfo().nativeLibraryDir;
        appDir = getApplicationContext().getFilesDir();
        a.setText("默认插件加载路径" + sharedDir);
        rightPlugins = findViewById(R.id.RightPlugins);
        checkAbi();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_PICK_FILE && resultCode == RESULT_OK) {
            Uri uri = data.getData();
            String srcAbsolutePath = null;
            // Android 4.4及以上使用兼容方法
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                srcAbsolutePath = UriPathResolver.getPath(this, uri);
            } else {
                // 低版本直接通过MediaStore获取
                String[] projection = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
                if (cursor != null && cursor.moveToFirst()) {
                    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                    srcAbsolutePath = cursor.getString(columnIndex);
                    cursor.close();
                }
            }
            String fileName = getFileNameFromUri(uri);
            File outputDir = new File(getApplicationContext().getExternalFilesDir(null), "trans");
            if (!outputDir.exists()) {
                outputDir.mkdir();
            }
            try {
                unzip(new File(srcAbsolutePath), outputDir.getAbsolutePath());
                onComplete(true, "解压成功，文件保存至：" + outputDir.getAbsolutePath());
                importLib(outputDir.getAbsolutePath());
            } catch (Exception e) {
                Log.d("uzip failed:",e.getMessage());
                onComplete(false, e.getMessage());
            }
        }
        //uri.getEncodedPath()
            /*File destFile = new File(getFilesDir(),fileName);
            try{
                InputStream inputStream = getContentResolver().openInputStream(uri);
                FileOutputStream fs = new FileOutputStream(destFile);
                byte[] buffer = new byte[1024];
                int len;
                while((len=inputStream.read(buffer))>0)
                {
                    fs.write(buffer,0,len);
                }
                onComplete(true,"文件导入成功");
            } catch(IOException e)
            {
                onComplete(false,"复制失败"+e.getMessage());
            }*/
    }

    private String getFileNameFromUri(Uri uri) {
        String name = "";
        try (Cursor cursor = getContentResolver().query(uri, null, null, null, null)) {
            if (cursor != null && cursor.moveToFirst()) {
                int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                name = cursor.getString(nameIndex);
            }
        }
        return name;
    }
    public void importPlugin(View v)  {
        // 高版本安卓10解决外部文件读取 计划都用这种方法
//        if(Build.VERSION.SDK_INT>Build.VERSION_CODES.Q)
//        {
//            Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
//            intent.addCategory(Intent.CATEGORY_OPENABLE);
//            intent.setType("*/*");
//            startActivityForResult(intent, REQUEST_CODE_PICK_FILE);
//        }
        // 需要补充不同版本安卓兼容方法
        Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        startActivityForResult(intent, REQUEST_CODE_PICK_FILE);
        /* 可用旧代码
        userImportDir = b.getText().toString();
        File dir = new File(userImportDir);
        if(dir.isDirectory())
        {
            //FileUtils.copyFile();
            try{
                FileUtils.copyFilesOnly(userImportDir,appDir.getAbsolutePath(),this);
            }catch (IOException e){e.printStackTrace();}
        }
        else{Toast.makeText(this,"错误，路径非法",Toast.LENGTH_LONG).show();}*/
    }
    public void refreshPlugin(View v)
    {
        if(rightPlugins.getChildCount()==0)
        {
            getAllPlugins(rightPlugins);
        }
        else if(rightPlugins.getChildCount()>0)
        {
            rightPlugins.removeAllViews();
            getAllPlugins(rightPlugins);
        }
    }
    private void getAllPlugins(LinearLayout rp)
    {
        File[] files = appDir.listFiles();
        for(File f:files)
        {
            TextView tv = new TextView(this);
            tv.setText(f.getName());
            rp.addView(tv);
        }
    }
    @Override
    public void onComplete(boolean success, String messages)
    {
        if(success)
        {
            Toast.makeText(getApplicationContext(),"导入完成",Toast.LENGTH_SHORT).show();
            File files[] = appDir.listFiles();
            for(File file:files)
            {
                Log.d("completeImport",file.getAbsolutePath());
                //debug.setText(file.getAbsolutePath());
            }
        }
        else{
            Toast.makeText(PluginManage.this,"失败" + messages,Toast.LENGTH_SHORT).show();
        }
    }
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public void checkAbi()
    {
        String[] abis = Build.SUPPORTED_ABIS;
        /*for(String abi:abis) {
            Log.d("支持的abi", abi);
        }*/
        // 系统自动排序，第一个就是最优abi
        bestAbi = abis[0];
    }
    public String getSoAbi(File soFile) throws IOException
    {
        try (RandomAccessFile raf = new RandomAccessFile(soFile, "r"))
        {
            // ELF文件头前16字节标识
            byte[] elfHeader = new byte[16];
            raf.read(elfHeader);

            // 检查ELF魔数（0x7F 0x45 0x4C 0x46）
            if (elfHeader[0] != 0x7F || elfHeader[1] != 'E' || elfHeader[2] != 'L' || elfHeader[3] != 'F') {
                return "invalid_elf";
            }

            // 解析e_machine字段（偏移0x12）
            raf.seek(0x12);
            int eMachine = raf.readShort() & 0xFFFF;

            // 映射e_machine到ABI
            switch (eMachine)
            {
                case 0x28: return "armeabi";      // ARMv5
                case 0x3E: return "x86_64";       // x86-64
                case 0xB7: return "arm64-v8a";    // AArch64
                default: return "unknown";
            }
        }
    }
    public void unzip(File zipFilePath,String destDir) throws Exception
    {
        try (ZipInputStream zipIn = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipFilePath)))) {
            ZipEntry entry;
            while ((entry = zipIn.getNextEntry()) != null) {
                String filePath = destDir + File.separator + entry.getName();
                if (entry.isDirectory()) {
                    new File(filePath).mkdirs(); // 创建目录
                } else {
                    extractFile(zipIn, filePath); // 写入文件
                }
                zipIn.closeEntry();
            }
        }
    }

    private void extractFile(ZipInputStream zipIn, String filePath) throws IOException
    {
        try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) {
            byte[] buffer = new byte[4096];
            int read;
            while ((read = zipIn.read(buffer)) != -1) {
                bos.write(buffer, 0, read);
            }
        }
    }

    // 一个导入so，一个导入界面文件 先测试libstringfromso.so
    public void importLib(String extractedFileDir)
    {
        File[] soDirs = new File(extractedFileDir).listFiles();
        for(File f:soDirs)
        {
            /*if(callback!=null)
            {
                //callback.onComplete(true,new File(destFile).getAbsolutePath());
            }*/
            String ff = f.getName();
            if (bestAbi.equals("v7a"))
            {
                FileUtils.copyFile(ff.concat("/v7a/libstringfromso.so"),getApplicationInfo().nativeLibraryDir);
            }
            else if(bestAbi.equals("v8a"))
            {
                FileUtils.copyFile(ff.concat("/v8a/libstringfromso.so"),getApplicationInfo().nativeLibraryDir);
            }
            else if(bestAbi.equals("x86"))
            {
                FileUtils.copyFile(ff.concat("/x86/libstringfromso.so"),getApplicationInfo().nativeLibraryDir);
            }
        }
        Toast.makeText(PluginManage.this,"插件库导入完成",Toast.LENGTH_SHORT).show();
        File f = new File(getApplicationInfo().nativeLibraryDir);
        File[] files = f.listFiles();
        for(File b:files)
        {
            Log.d("soImported",b.getAbsolutePath());
        }
        //debug.setText(getApplicationInfo().nativeLibraryDir);
    }
    public void importUI()
    {

    }
}